using System.Linq;

using Xamarin.Tests;

namespace GeneratorTests {
	[TestFixture ()]
	[Parallelizable (ParallelScope.All)]
	public class ProtocolTests : BGenBase {
		[TestCase (Profile.MacCatalyst)]
		[TestCase (Profile.iOS)]
		public void Members (Profile profile)
		{
			var bgen = BuildFile (profile, "tests/protocols.cs");

			var allTypeDefinitions = bgen.ApiAssembly.MainModule.GetTypes ().ToArray ();
			var allTypes = allTypeDefinitions.Select (v => v.FullName).OrderBy (v => v).ToArray ();
			var expectedTypes = new string [] {
				"<Module>",
				"api0.Messaging",
				"Protocols.IProtocolWithConstructors",
				"Protocols.IProtocolWithStaticMembers",
				"Protocols.ProtocolWithConstructorsWrapper",
				"Protocols.ProtocolWithStaticMembersWrapper",
				"ObjCRuntime.Trampolines",
				"ObjCRuntime.Trampolines/DAction",
				"ObjCRuntime.Trampolines/NIDAction",
				"ObjCRuntime.Trampolines/SDAction",
				"Protocols.IOptionalProtocol",
				"Protocols.IOptionalProtocol/<>c__DisplayClass6_0",
				"Protocols.IOptionalProtocol/<>c__DisplayClass9_0`1",
				"Protocols.IOptionalProtocolCompat",
				"Protocols.IRequiredProtocol",
				"Protocols.IRequiredProtocol/<>c__DisplayClass6_0",
				"Protocols.IRequiredProtocol/<>c__DisplayClass9_0`1",
				"Protocols.IRequiredProtocolCompat",
				"Protocols.IRequiredProtocolCompatWithExtensions",
				"Protocols.MyObject",
				"Protocols.MyObject/<>c__DisplayClass12_0",
				"Protocols.MyObject/<>c__DisplayClass15_0",
				"Protocols.MyObject/<>c__DisplayClass18_0",
				"Protocols.MyObject/<>c__DisplayClass9_0",
				"Protocols.MyObject2",
				"Protocols.OptionalProtocolCompat_Extensions",
				"Protocols.OptionalProtocolCompatWrapper",
				"Protocols.OptionalProtocolWrapper",
				"Protocols.RequiredProtocolCompatWithExtensions_Extensions",
				"Protocols.RequiredProtocolCompatWithExtensionsWrapper",
				"Protocols.RequiredProtocolCompatWrapper",
				"Protocols.RequiredProtocolWrapper",
			};
			var missingTypes = expectedTypes.Except (allTypes);
			var extraTypes = allTypes.Except (expectedTypes);

			if (missingTypes.Any () || extraTypes.Any ()) {
				Console.WriteLine ("Expected Types (formatted to be copy-pasted into ProtocolTests.cs):");
				foreach (var t in allTypes)
					Console.WriteLine ($"				\"{t}\",");
			}

			Assert.That (missingTypes, Is.Empty, "Missing Types");
			Assert.That (extraTypes, Is.Empty, "Extra Types");

			var allMethods = allTypeDefinitions.SelectMany (v => v.Methods).Select (v => v.ToString ()).OrderBy (v => v).ToArray ();
			var expectedMethods = new string [] {
				"Foundation.NSDate Protocols.IProtocolWithStaticMembers::GetDateProperty()",
				"Foundation.NSObject Protocols.IOptionalProtocol::_GetOptionalPropertyWeakSemantics(Protocols.IOptionalProtocol)",
				"Foundation.NSObject Protocols.IOptionalProtocol::get_OptionalPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.IOptionalProtocol::GetStaticOptionalPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.IOptionalProtocolCompat::_GetOptionalPropertyWeakSemantics(Protocols.IOptionalProtocolCompat)",
				"Foundation.NSObject Protocols.IOptionalProtocolCompat::get_OptionalPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.IOptionalProtocolCompat::GetStaticOptionalPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.IRequiredProtocol::_GetRequiredPropertyWeakSemantics(Protocols.IRequiredProtocol)",
				"Foundation.NSObject Protocols.IRequiredProtocol::get_RequiredPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.IRequiredProtocol::GetStaticRequiredPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.IRequiredProtocolCompat::_GetRequiredPropertyWeakSemantics(Protocols.IRequiredProtocolCompat)",
				"Foundation.NSObject Protocols.IRequiredProtocolCompat::get_RequiredPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.IRequiredProtocolCompat::GetStaticRequiredPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.IRequiredProtocolCompatWithExtensions::_GetRequiredPropertyWeakSemantics(Protocols.IRequiredProtocolCompatWithExtensions)",
				"Foundation.NSObject Protocols.IRequiredProtocolCompatWithExtensions::get_RequiredPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.IRequiredProtocolCompatWithExtensions::GetStaticRequiredPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.MyObject::get_OptionalPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.MyObject::get_RequiredPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.MyObject::get_StaticOptionalPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.MyObject::get_StaticRequiredPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.MyObject2::get_OptionalPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.MyObject2::get_RequiredPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.MyObject2::get_StaticOptionalPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.MyObject2::get_StaticRequiredPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.OptionalProtocolCompat_Extensions::GetOptionalPropertyWeakSemantics(Protocols.IOptionalProtocolCompat)",
				"Foundation.NSObject Protocols.RequiredProtocolCompatWithExtensions_Extensions::GetRequiredPropertyWeakSemantics(Protocols.IRequiredProtocolCompatWithExtensions)",
				"Foundation.NSObject Protocols.RequiredProtocolCompatWithExtensionsWrapper::get_RequiredPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.RequiredProtocolCompatWrapper::get_RequiredPropertyWeakSemantics()",
				"Foundation.NSObject Protocols.RequiredProtocolWrapper::get_RequiredPropertyWeakSemantics()",
				"Foundation.NSString Protocols.IProtocolWithStaticMembers::Method(Foundation.NSDate)",
				"ObjCRuntime.BlockLiteral ObjCRuntime.Trampolines/SDAction::CreateBlock(System.Action)",
				"ObjCRuntime.BlockLiteral ObjCRuntime.Trampolines/SDAction::CreateNullableBlock(System.Action)",
				"ObjCRuntime.NativeHandle api0.Messaging::NativeHandle_objc_msgSend_NativeHandle(System.IntPtr,System.IntPtr,ObjCRuntime.NativeHandle)",
				"ObjCRuntime.NativeHandle api0.Messaging::NativeHandle_objc_msgSend_ref_NativeHandle(System.IntPtr,System.IntPtr,ObjCRuntime.NativeHandle*)",
				"ObjCRuntime.NativeHandle api0.Messaging::NativeHandle_objc_msgSend(System.IntPtr,System.IntPtr)",
				"ObjCRuntime.NativeHandle api0.Messaging::NativeHandle_objc_msgSendSuper_NativeHandle(System.IntPtr,System.IntPtr,ObjCRuntime.NativeHandle)",
				"ObjCRuntime.NativeHandle api0.Messaging::NativeHandle_objc_msgSendSuper_ref_NativeHandle(System.IntPtr,System.IntPtr,ObjCRuntime.NativeHandle*)",
				"ObjCRuntime.NativeHandle api0.Messaging::NativeHandle_objc_msgSendSuper(System.IntPtr,System.IntPtr)",
				"ObjCRuntime.NativeHandle Protocols.IProtocolWithStaticMembers::Method()",
				"ObjCRuntime.NativeHandle Protocols.MyObject::get_ClassHandle()",
				"ObjCRuntime.NativeHandle Protocols.MyObject2::get_ClassHandle()",
				"System.Action ObjCRuntime.Trampolines/NIDAction::Create(System.IntPtr)",
				"System.Boolean Protocols.IProtocolWithStaticMembers::GetProperty()",
				"System.Byte api0.Messaging::bool_objc_msgSend(System.IntPtr,System.IntPtr)",
				"System.Byte api0.Messaging::bool_objc_msgSendSuper(System.IntPtr,System.IntPtr)",
				"System.IAsyncResult ObjCRuntime.Trampolines/DAction::BeginInvoke(System.IntPtr,System.AsyncCallback,System.Object)",
				"System.Int32 api0.Messaging::int_objc_msgSend_int_out_Byte_ref_Int16(System.IntPtr,System.IntPtr,System.Int32,System.Byte*,System.Int16*)",
				"System.Int32 api0.Messaging::int_objc_msgSend_NativeHandle(System.IntPtr,System.IntPtr,ObjCRuntime.NativeHandle)",
				"System.Int32 api0.Messaging::int_objc_msgSend(System.IntPtr,System.IntPtr)",
				"System.Int32 api0.Messaging::int_objc_msgSendSuper_int_out_Byte_ref_Int16(System.IntPtr,System.IntPtr,System.Int32,System.Byte*,System.Int16*)",
				"System.Int32 api0.Messaging::int_objc_msgSendSuper_NativeHandle(System.IntPtr,System.IntPtr,ObjCRuntime.NativeHandle)",
				"System.Int32 api0.Messaging::int_objc_msgSendSuper(System.IntPtr,System.IntPtr)",
				"System.Int32 Protocols.IOptionalProtocol::_GetInternalOptionalProperty(Protocols.IOptionalProtocol)",
				"System.Int32 Protocols.IOptionalProtocol::_GetOptionalProperty(Protocols.IOptionalProtocol)",
				"System.Int32 Protocols.IOptionalProtocol::_InternalOptionalMethod(Protocols.IOptionalProtocol,System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IOptionalProtocol::_OptionalMethod(Protocols.IOptionalProtocol,System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IOptionalProtocol::get_InternalOptionalProperty()",
				"System.Int32 Protocols.IOptionalProtocol::get_OptionalProperty()",
				"System.Int32 Protocols.IOptionalProtocol::GetStaticOptionalProperty()",
				"System.Int32 Protocols.IOptionalProtocol::InternalOptionalMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IOptionalProtocol::OptionalMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IOptionalProtocol::StaticOptionalMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IOptionalProtocolCompat::_GetInternalOptionalProperty(Protocols.IOptionalProtocolCompat)",
				"System.Int32 Protocols.IOptionalProtocolCompat::_GetOptionalProperty(Protocols.IOptionalProtocolCompat)",
				"System.Int32 Protocols.IOptionalProtocolCompat::_InternalOptionalMethod(Protocols.IOptionalProtocolCompat,System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IOptionalProtocolCompat::_OptionalMethod(Protocols.IOptionalProtocolCompat,System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IOptionalProtocolCompat::get_InternalOptionalProperty()",
				"System.Int32 Protocols.IOptionalProtocolCompat::get_OptionalProperty()",
				"System.Int32 Protocols.IOptionalProtocolCompat::GetStaticOptionalProperty()",
				"System.Int32 Protocols.IOptionalProtocolCompat::InternalOptionalMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IOptionalProtocolCompat::OptionalMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IOptionalProtocolCompat::StaticOptionalMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IProtocolWithStaticMembers::Method(System.String)",
				"System.Int32 Protocols.IRequiredProtocol::_GetInternalRequiredProperty(Protocols.IRequiredProtocol)",
				"System.Int32 Protocols.IRequiredProtocol::_GetRequiredProperty(Protocols.IRequiredProtocol)",
				"System.Int32 Protocols.IRequiredProtocol::_InternalRequiredMethod(Protocols.IRequiredProtocol,System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IRequiredProtocol::_RequiredMethod(Protocols.IRequiredProtocol,System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IRequiredProtocol::get_InternalRequiredProperty()",
				"System.Int32 Protocols.IRequiredProtocol::get_RequiredProperty()",
				"System.Int32 Protocols.IRequiredProtocol::GetStaticRequiredProperty()",
				"System.Int32 Protocols.IRequiredProtocol::InternalRequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IRequiredProtocol::RequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IRequiredProtocol::StaticRequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IRequiredProtocolCompat::_GetInternalRequiredProperty(Protocols.IRequiredProtocolCompat)",
				"System.Int32 Protocols.IRequiredProtocolCompat::_GetRequiredProperty(Protocols.IRequiredProtocolCompat)",
				"System.Int32 Protocols.IRequiredProtocolCompat::_InternalRequiredMethod(Protocols.IRequiredProtocolCompat,System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IRequiredProtocolCompat::_RequiredMethod(Protocols.IRequiredProtocolCompat,System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IRequiredProtocolCompat::get_InternalRequiredProperty()",
				"System.Int32 Protocols.IRequiredProtocolCompat::get_RequiredProperty()",
				"System.Int32 Protocols.IRequiredProtocolCompat::GetStaticRequiredProperty()",
				"System.Int32 Protocols.IRequiredProtocolCompat::InternalRequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IRequiredProtocolCompat::RequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IRequiredProtocolCompat::StaticRequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IRequiredProtocolCompatWithExtensions::_GetInternalRequiredProperty(Protocols.IRequiredProtocolCompatWithExtensions)",
				"System.Int32 Protocols.IRequiredProtocolCompatWithExtensions::_GetRequiredProperty(Protocols.IRequiredProtocolCompatWithExtensions)",
				"System.Int32 Protocols.IRequiredProtocolCompatWithExtensions::_InternalRequiredMethod(Protocols.IRequiredProtocolCompatWithExtensions,System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IRequiredProtocolCompatWithExtensions::_RequiredMethod(Protocols.IRequiredProtocolCompatWithExtensions,System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IRequiredProtocolCompatWithExtensions::get_InternalRequiredProperty()",
				"System.Int32 Protocols.IRequiredProtocolCompatWithExtensions::get_RequiredProperty()",
				"System.Int32 Protocols.IRequiredProtocolCompatWithExtensions::GetStaticRequiredProperty()",
				"System.Int32 Protocols.IRequiredProtocolCompatWithExtensions::InternalRequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IRequiredProtocolCompatWithExtensions::RequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.IRequiredProtocolCompatWithExtensions::StaticRequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.MyObject::get_InternalOptionalProperty()",
				"System.Int32 Protocols.MyObject::get_InternalRequiredProperty()",
				"System.Int32 Protocols.MyObject::get_OptionalProperty()",
				"System.Int32 Protocols.MyObject::get_RequiredProperty()",
				"System.Int32 Protocols.MyObject::get_StaticOptionalProperty()",
				"System.Int32 Protocols.MyObject::get_StaticRequiredProperty()",
				"System.Int32 Protocols.MyObject::InternalOptionalMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.MyObject::InternalRequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.MyObject::OptionalMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.MyObject::RequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.MyObject::StaticOptionalMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.MyObject::StaticRequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.MyObject2::get_InternalOptionalProperty()",
				"System.Int32 Protocols.MyObject2::get_InternalRequiredProperty()",
				"System.Int32 Protocols.MyObject2::get_OptionalProperty()",
				"System.Int32 Protocols.MyObject2::get_RequiredProperty()",
				"System.Int32 Protocols.MyObject2::get_StaticOptionalProperty()",
				"System.Int32 Protocols.MyObject2::get_StaticRequiredProperty()",
				"System.Int32 Protocols.MyObject2::InternalOptionalMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.MyObject2::InternalRequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.MyObject2::OptionalMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.MyObject2::RequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.MyObject2::StaticOptionalMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.MyObject2::StaticRequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.OptionalProtocolCompat_Extensions::GetInternalOptionalProperty(Protocols.IOptionalProtocolCompat)",
				"System.Int32 Protocols.OptionalProtocolCompat_Extensions::GetOptionalProperty(Protocols.IOptionalProtocolCompat)",
				"System.Int32 Protocols.OptionalProtocolCompat_Extensions::InternalOptionalMethod(Protocols.IOptionalProtocolCompat,System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.OptionalProtocolCompat_Extensions::OptionalMethod(Protocols.IOptionalProtocolCompat,System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.RequiredProtocolCompatWithExtensions_Extensions::GetInternalRequiredProperty(Protocols.IRequiredProtocolCompatWithExtensions)",
				"System.Int32 Protocols.RequiredProtocolCompatWithExtensions_Extensions::GetRequiredProperty(Protocols.IRequiredProtocolCompatWithExtensions)",
				"System.Int32 Protocols.RequiredProtocolCompatWithExtensions_Extensions::InternalRequiredMethod(Protocols.IRequiredProtocolCompatWithExtensions,System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.RequiredProtocolCompatWithExtensions_Extensions::RequiredMethod(Protocols.IRequiredProtocolCompatWithExtensions,System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.RequiredProtocolCompatWithExtensionsWrapper::get_InternalRequiredProperty()",
				"System.Int32 Protocols.RequiredProtocolCompatWithExtensionsWrapper::get_RequiredProperty()",
				"System.Int32 Protocols.RequiredProtocolCompatWithExtensionsWrapper::InternalRequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.RequiredProtocolCompatWithExtensionsWrapper::RequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.RequiredProtocolCompatWrapper::get_InternalRequiredProperty()",
				"System.Int32 Protocols.RequiredProtocolCompatWrapper::get_RequiredProperty()",
				"System.Int32 Protocols.RequiredProtocolCompatWrapper::InternalRequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.RequiredProtocolCompatWrapper::RequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.RequiredProtocolWrapper::get_InternalRequiredProperty()",
				"System.Int32 Protocols.RequiredProtocolWrapper::get_RequiredProperty()",
				"System.Int32 Protocols.RequiredProtocolWrapper::InternalRequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.Int32 Protocols.RequiredProtocolWrapper::RequiredMethod(System.Int32,System.Byte&,System.Int16&)",
				"System.IntPtr api0.Messaging::IntPtr_objc_msgSend_IntPtr(System.IntPtr,System.IntPtr,System.IntPtr)",
				"System.IntPtr api0.Messaging::IntPtr_objc_msgSend(System.IntPtr,System.IntPtr)",
				"System.IntPtr api0.Messaging::IntPtr_objc_msgSendSuper_IntPtr(System.IntPtr,System.IntPtr,System.IntPtr)",
				"System.IntPtr api0.Messaging::IntPtr_objc_msgSendSuper(System.IntPtr,System.IntPtr)",
				"System.String Protocols.IOptionalProtocol::_GetNullableOptionalProperty(Protocols.IOptionalProtocol)",
				"System.String Protocols.IOptionalProtocol::get_NullableOptionalProperty()",
				"System.String Protocols.IOptionalProtocol::GetNullableStaticOptionalProperty()",
				"System.String Protocols.IProtocolWithStaticMembers::GetStringProperty()",
				"System.String Protocols.IProtocolWithStaticMembers::Method(Foundation.NSError&)",
				"System.String Protocols.IRequiredProtocol::_GetNullableRequiredProperty(Protocols.IRequiredProtocol)",
				"System.String Protocols.IRequiredProtocol::get_NullableRequiredProperty()",
				"System.String Protocols.IRequiredProtocol::GetNullableStaticRequiredProperty()",
				"System.String Protocols.MyObject::get_NullableOptionalProperty()",
				"System.String Protocols.MyObject::get_NullableRequiredProperty()",
				"System.String Protocols.MyObject::get_NullableStaticOptionalProperty()",
				"System.String Protocols.MyObject::get_NullableStaticRequiredProperty()",
				"System.String Protocols.RequiredProtocolWrapper::get_NullableRequiredProperty()",
				"System.Threading.Tasks.Task Protocols.IOptionalProtocol::OptionalAsyncMethodAsync()",
				"System.Threading.Tasks.Task Protocols.IOptionalProtocol::StaticOptionalAsyncMethodAsync()",
				"System.Threading.Tasks.Task Protocols.IRequiredProtocol::RequiredAsyncMethodAsync()",
				"System.Threading.Tasks.Task Protocols.IRequiredProtocol::StaticRequiredAsyncMethodAsync()",
				"System.Threading.Tasks.Task Protocols.MyObject::OptionalAsyncMethodAsync()",
				"System.Threading.Tasks.Task Protocols.MyObject::RequiredAsyncMethodAsync()",
				"System.Threading.Tasks.Task Protocols.MyObject::StaticOptionalAsyncMethodAsync()",
				"System.Threading.Tasks.Task Protocols.MyObject::StaticRequiredAsyncMethodAsync()",
				"System.Void api0.Messaging::.cctor()",
				"System.Void api0.Messaging::void_objc_msgSend_bool(System.IntPtr,System.IntPtr,System.Byte)",
				"System.Void api0.Messaging::void_objc_msgSend_int(System.IntPtr,System.IntPtr,System.Int32)",
				"System.Void api0.Messaging::void_objc_msgSend_NativeHandle(System.IntPtr,System.IntPtr,ObjCRuntime.NativeHandle)",
				"System.Void api0.Messaging::void_objc_msgSendSuper_bool(System.IntPtr,System.IntPtr,System.Byte)",
				"System.Void api0.Messaging::void_objc_msgSendSuper_int(System.IntPtr,System.IntPtr,System.Int32)",
				"System.Void api0.Messaging::void_objc_msgSendSuper_NativeHandle(System.IntPtr,System.IntPtr,ObjCRuntime.NativeHandle)",
				"System.Void ObjCRuntime.Trampolines/DAction::.ctor(System.Object,System.IntPtr)",
				"System.Void ObjCRuntime.Trampolines/DAction::EndInvoke(System.IAsyncResult)",
				"System.Void ObjCRuntime.Trampolines/DAction::Invoke(System.IntPtr)",
				"System.Void ObjCRuntime.Trampolines/NIDAction::.cctor()",
				"System.Void ObjCRuntime.Trampolines/NIDAction::.ctor(ObjCRuntime.BlockLiteral*)",
				"System.Void ObjCRuntime.Trampolines/NIDAction::Invoke()",
				"System.Void ObjCRuntime.Trampolines/SDAction::Invoke(System.IntPtr)",
				"System.Void Protocols.IOptionalProtocol::_OptionalAsyncMethod(Protocols.IOptionalProtocol,System.Action)",
				"System.Void Protocols.IOptionalProtocol::_SetInternalOptionalProperty(Protocols.IOptionalProtocol,System.Int32)",
				"System.Void Protocols.IOptionalProtocol::_SetNullableOptionalProperty(Protocols.IOptionalProtocol,System.String)",
				"System.Void Protocols.IOptionalProtocol::_SetOptionalProperty(Protocols.IOptionalProtocol,System.Int32)",
				"System.Void Protocols.IOptionalProtocol::_SetOptionalPropertyWeakSemantics(Protocols.IOptionalProtocol,Foundation.NSObject)",
				"System.Void Protocols.IOptionalProtocol::.cctor()",
				"System.Void Protocols.IOptionalProtocol::OptionalAsyncMethod(System.Action)",
				"System.Void Protocols.IOptionalProtocol::set_InternalOptionalProperty(System.Int32)",
				"System.Void Protocols.IOptionalProtocol::set_NullableOptionalProperty(System.String)",
				"System.Void Protocols.IOptionalProtocol::set_OptionalProperty(System.Int32)",
				"System.Void Protocols.IOptionalProtocol::set_OptionalPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.IOptionalProtocol::SetNullableStaticOptionalProperty(System.String)",
				"System.Void Protocols.IOptionalProtocol::SetStaticOptionalProperty(System.Int32)",
				"System.Void Protocols.IOptionalProtocol::SetStaticOptionalPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.IOptionalProtocol::StaticOptionalAsyncMethod(System.Action)",
				"System.Void Protocols.IOptionalProtocol/<>c__DisplayClass6_0::.ctor()",
				"System.Void Protocols.IOptionalProtocol/<>c__DisplayClass6_0::<OptionalAsyncMethodAsync>b__0()",
				"System.Void Protocols.IOptionalProtocol/<>c__DisplayClass9_0`1::.ctor()",
				"System.Void Protocols.IOptionalProtocol/<>c__DisplayClass9_0`1::<StaticOptionalAsyncMethodAsync>b__0()",
				"System.Void Protocols.IOptionalProtocolCompat::_SetInternalOptionalProperty(Protocols.IOptionalProtocolCompat,System.Int32)",
				"System.Void Protocols.IOptionalProtocolCompat::_SetOptionalProperty(Protocols.IOptionalProtocolCompat,System.Int32)",
				"System.Void Protocols.IOptionalProtocolCompat::_SetOptionalPropertyWeakSemantics(Protocols.IOptionalProtocolCompat,Foundation.NSObject)",
				"System.Void Protocols.IOptionalProtocolCompat::.cctor()",
				"System.Void Protocols.IOptionalProtocolCompat::set_InternalOptionalProperty(System.Int32)",
				"System.Void Protocols.IOptionalProtocolCompat::set_OptionalProperty(System.Int32)",
				"System.Void Protocols.IOptionalProtocolCompat::set_OptionalPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.IOptionalProtocolCompat::SetStaticOptionalProperty(System.Int32)",
				"System.Void Protocols.IOptionalProtocolCompat::SetStaticOptionalPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.IProtocolWithConstructors::.cctor()",
				"System.Void Protocols.IProtocolWithStaticMembers::.cctor()",
				"System.Void Protocols.IProtocolWithStaticMembers::SetDateProperty(Foundation.NSDate)",
				"System.Void Protocols.IProtocolWithStaticMembers::SetProperty(System.Boolean)",
				"System.Void Protocols.IProtocolWithStaticMembers::SetStringProperty(System.String)",
				"System.Void Protocols.IRequiredProtocol::_RequiredAsyncMethod(Protocols.IRequiredProtocol,System.Action)",
				"System.Void Protocols.IRequiredProtocol::_SetInternalRequiredProperty(Protocols.IRequiredProtocol,System.Int32)",
				"System.Void Protocols.IRequiredProtocol::_SetNullableRequiredProperty(Protocols.IRequiredProtocol,System.String)",
				"System.Void Protocols.IRequiredProtocol::_SetRequiredProperty(Protocols.IRequiredProtocol,System.Int32)",
				"System.Void Protocols.IRequiredProtocol::_SetRequiredPropertyWeakSemantics(Protocols.IRequiredProtocol,Foundation.NSObject)",
				"System.Void Protocols.IRequiredProtocol::.cctor()",
				"System.Void Protocols.IRequiredProtocol::RequiredAsyncMethod(System.Action)",
				"System.Void Protocols.IRequiredProtocol::set_InternalRequiredProperty(System.Int32)",
				"System.Void Protocols.IRequiredProtocol::set_NullableRequiredProperty(System.String)",
				"System.Void Protocols.IRequiredProtocol::set_RequiredProperty(System.Int32)",
				"System.Void Protocols.IRequiredProtocol::set_RequiredPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.IRequiredProtocol::SetNullableStaticRequiredProperty(System.String)",
				"System.Void Protocols.IRequiredProtocol::SetStaticRequiredProperty(System.Int32)",
				"System.Void Protocols.IRequiredProtocol::SetStaticRequiredPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.IRequiredProtocol::StaticRequiredAsyncMethod(System.Action)",
				"System.Void Protocols.IRequiredProtocol/<>c__DisplayClass6_0::.ctor()",
				"System.Void Protocols.IRequiredProtocol/<>c__DisplayClass6_0::<RequiredAsyncMethodAsync>b__0()",
				"System.Void Protocols.IRequiredProtocol/<>c__DisplayClass9_0`1::.ctor()",
				"System.Void Protocols.IRequiredProtocol/<>c__DisplayClass9_0`1::<StaticRequiredAsyncMethodAsync>b__0()",
				"System.Void Protocols.IRequiredProtocolCompat::_SetInternalRequiredProperty(Protocols.IRequiredProtocolCompat,System.Int32)",
				"System.Void Protocols.IRequiredProtocolCompat::_SetRequiredProperty(Protocols.IRequiredProtocolCompat,System.Int32)",
				"System.Void Protocols.IRequiredProtocolCompat::_SetRequiredPropertyWeakSemantics(Protocols.IRequiredProtocolCompat,Foundation.NSObject)",
				"System.Void Protocols.IRequiredProtocolCompat::.cctor()",
				"System.Void Protocols.IRequiredProtocolCompat::set_InternalRequiredProperty(System.Int32)",
				"System.Void Protocols.IRequiredProtocolCompat::set_RequiredProperty(System.Int32)",
				"System.Void Protocols.IRequiredProtocolCompat::set_RequiredPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.IRequiredProtocolCompat::SetStaticRequiredProperty(System.Int32)",
				"System.Void Protocols.IRequiredProtocolCompat::SetStaticRequiredPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.IRequiredProtocolCompatWithExtensions::_SetInternalRequiredProperty(Protocols.IRequiredProtocolCompatWithExtensions,System.Int32)",
				"System.Void Protocols.IRequiredProtocolCompatWithExtensions::_SetRequiredProperty(Protocols.IRequiredProtocolCompatWithExtensions,System.Int32)",
				"System.Void Protocols.IRequiredProtocolCompatWithExtensions::_SetRequiredPropertyWeakSemantics(Protocols.IRequiredProtocolCompatWithExtensions,Foundation.NSObject)",
				"System.Void Protocols.IRequiredProtocolCompatWithExtensions::.cctor()",
				"System.Void Protocols.IRequiredProtocolCompatWithExtensions::set_InternalRequiredProperty(System.Int32)",
				"System.Void Protocols.IRequiredProtocolCompatWithExtensions::set_RequiredProperty(System.Int32)",
				"System.Void Protocols.IRequiredProtocolCompatWithExtensions::set_RequiredPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.IRequiredProtocolCompatWithExtensions::SetStaticRequiredProperty(System.Int32)",
				"System.Void Protocols.IRequiredProtocolCompatWithExtensions::SetStaticRequiredPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.MyObject::.cctor()",
				"System.Void Protocols.MyObject::.ctor()",
				"System.Void Protocols.MyObject::.ctor(Foundation.NSObjectFlag)",
				"System.Void Protocols.MyObject::.ctor(ObjCRuntime.NativeHandle)",
				"System.Void Protocols.MyObject::Dispose(System.Boolean)",
				"System.Void Protocols.MyObject::OptionalAsyncMethod(System.Action)",
				"System.Void Protocols.MyObject::RequiredAsyncMethod(System.Action)",
				"System.Void Protocols.MyObject::set_InternalOptionalProperty(System.Int32)",
				"System.Void Protocols.MyObject::set_InternalRequiredProperty(System.Int32)",
				"System.Void Protocols.MyObject::set_NullableOptionalProperty(System.String)",
				"System.Void Protocols.MyObject::set_NullableRequiredProperty(System.String)",
				"System.Void Protocols.MyObject::set_NullableStaticOptionalProperty(System.String)",
				"System.Void Protocols.MyObject::set_NullableStaticRequiredProperty(System.String)",
				"System.Void Protocols.MyObject::set_OptionalProperty(System.Int32)",
				"System.Void Protocols.MyObject::set_OptionalPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.MyObject::set_RequiredProperty(System.Int32)",
				"System.Void Protocols.MyObject::set_RequiredPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.MyObject::set_StaticOptionalProperty(System.Int32)",
				"System.Void Protocols.MyObject::set_StaticOptionalPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.MyObject::set_StaticRequiredProperty(System.Int32)",
				"System.Void Protocols.MyObject::set_StaticRequiredPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.MyObject::StaticOptionalAsyncMethod(System.Action)",
				"System.Void Protocols.MyObject::StaticRequiredAsyncMethod(System.Action)",
				"System.Void Protocols.MyObject/<>c__DisplayClass12_0::.ctor()",
				"System.Void Protocols.MyObject/<>c__DisplayClass12_0::<RequiredAsyncMethodAsync>b__0()",
				"System.Void Protocols.MyObject/<>c__DisplayClass15_0::.ctor()",
				"System.Void Protocols.MyObject/<>c__DisplayClass15_0::<StaticOptionalAsyncMethodAsync>b__0()",
				"System.Void Protocols.MyObject/<>c__DisplayClass18_0::.ctor()",
				"System.Void Protocols.MyObject/<>c__DisplayClass18_0::<StaticRequiredAsyncMethodAsync>b__0()",
				"System.Void Protocols.MyObject/<>c__DisplayClass9_0::.ctor()",
				"System.Void Protocols.MyObject/<>c__DisplayClass9_0::<OptionalAsyncMethodAsync>b__0()",
				"System.Void Protocols.MyObject2::.cctor()",
				"System.Void Protocols.MyObject2::.ctor()",
				"System.Void Protocols.MyObject2::.ctor(Foundation.NSObjectFlag)",
				"System.Void Protocols.MyObject2::.ctor(ObjCRuntime.NativeHandle)",
				"System.Void Protocols.MyObject2::Dispose(System.Boolean)",
				"System.Void Protocols.MyObject2::set_InternalOptionalProperty(System.Int32)",
				"System.Void Protocols.MyObject2::set_InternalRequiredProperty(System.Int32)",
				"System.Void Protocols.MyObject2::set_OptionalProperty(System.Int32)",
				"System.Void Protocols.MyObject2::set_OptionalPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.MyObject2::set_RequiredProperty(System.Int32)",
				"System.Void Protocols.MyObject2::set_RequiredPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.MyObject2::set_StaticOptionalProperty(System.Int32)",
				"System.Void Protocols.MyObject2::set_StaticOptionalPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.MyObject2::set_StaticRequiredProperty(System.Int32)",
				"System.Void Protocols.MyObject2::set_StaticRequiredPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.OptionalProtocolCompat_Extensions::SetInternalOptionalProperty(Protocols.IOptionalProtocolCompat,System.Int32)",
				"System.Void Protocols.OptionalProtocolCompat_Extensions::SetOptionalProperty(Protocols.IOptionalProtocolCompat,System.Int32)",
				"System.Void Protocols.OptionalProtocolCompat_Extensions::SetOptionalPropertyWeakSemantics(Protocols.IOptionalProtocolCompat,Foundation.NSObject)",
				"System.Void Protocols.OptionalProtocolCompatWrapper::.cctor()",
				"System.Void Protocols.OptionalProtocolCompatWrapper::.ctor(ObjCRuntime.NativeHandle,System.Boolean)",
				"System.Void Protocols.OptionalProtocolWrapper::.cctor()",
				"System.Void Protocols.OptionalProtocolWrapper::.ctor(ObjCRuntime.NativeHandle,System.Boolean)",
				"System.Void Protocols.ProtocolWithConstructorsWrapper::.cctor()",
				"System.Void Protocols.ProtocolWithConstructorsWrapper::.ctor(ObjCRuntime.NativeHandle,System.Boolean)",
				"System.Void Protocols.ProtocolWithStaticMembersWrapper::.cctor()",
				"System.Void Protocols.ProtocolWithStaticMembersWrapper::.ctor(ObjCRuntime.NativeHandle,System.Boolean)",
				"System.Void Protocols.RequiredProtocolCompatWithExtensions_Extensions::SetInternalRequiredProperty(Protocols.IRequiredProtocolCompatWithExtensions,System.Int32)",
				"System.Void Protocols.RequiredProtocolCompatWithExtensions_Extensions::SetRequiredProperty(Protocols.IRequiredProtocolCompatWithExtensions,System.Int32)",
				"System.Void Protocols.RequiredProtocolCompatWithExtensions_Extensions::SetRequiredPropertyWeakSemantics(Protocols.IRequiredProtocolCompatWithExtensions,Foundation.NSObject)",
				"System.Void Protocols.RequiredProtocolCompatWithExtensionsWrapper::.cctor()",
				"System.Void Protocols.RequiredProtocolCompatWithExtensionsWrapper::.ctor(ObjCRuntime.NativeHandle,System.Boolean)",
				"System.Void Protocols.RequiredProtocolCompatWithExtensionsWrapper::set_InternalRequiredProperty(System.Int32)",
				"System.Void Protocols.RequiredProtocolCompatWithExtensionsWrapper::set_RequiredProperty(System.Int32)",
				"System.Void Protocols.RequiredProtocolCompatWithExtensionsWrapper::set_RequiredPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.RequiredProtocolCompatWrapper::.cctor()",
				"System.Void Protocols.RequiredProtocolCompatWrapper::.ctor(ObjCRuntime.NativeHandle,System.Boolean)",
				"System.Void Protocols.RequiredProtocolCompatWrapper::set_InternalRequiredProperty(System.Int32)",
				"System.Void Protocols.RequiredProtocolCompatWrapper::set_RequiredProperty(System.Int32)",
				"System.Void Protocols.RequiredProtocolCompatWrapper::set_RequiredPropertyWeakSemantics(Foundation.NSObject)",
				"System.Void Protocols.RequiredProtocolWrapper::.cctor()",
				"System.Void Protocols.RequiredProtocolWrapper::.ctor(ObjCRuntime.NativeHandle,System.Boolean)",
				"System.Void Protocols.RequiredProtocolWrapper::RequiredAsyncMethod(System.Action)",
				"System.Void Protocols.RequiredProtocolWrapper::set_InternalRequiredProperty(System.Int32)",
				"System.Void Protocols.RequiredProtocolWrapper::set_NullableRequiredProperty(System.String)",
				"System.Void Protocols.RequiredProtocolWrapper::set_RequiredProperty(System.Int32)",
				"System.Void Protocols.RequiredProtocolWrapper::set_RequiredPropertyWeakSemantics(Foundation.NSObject)",
				"T Protocols.IProtocolWithConstructors::Create(Foundation.NSDate)",
				"T Protocols.IProtocolWithConstructors::CreateInstance()",
				"T Protocols.IProtocolWithConstructors::CreateInstance(Foundation.NSError&)",
				"T Protocols.IProtocolWithConstructors::CreateInstance(System.String)",
			};

			var missingMethods = expectedMethods.Except (allMethods);
			var extraMethods = allMethods.Except (expectedMethods);

			if (missingMethods.Any () || extraMethods.Any ()) {
				Console.WriteLine ("Expected Methods (formatted to be copy-pasted into ProtocolTests.cs):");
				foreach (var t in allMethods)
					Console.WriteLine ($"				\"{t}\",");
			}

			Assert.That (missingMethods, Is.Empty, "Missing Methods");
			Assert.That (extraMethods, Is.Empty, "Extra Methods");
		}
	}
}

